#include "Module/ModuleRegistry.hpp"
#include "Module/DefaultModule.hpp"
#include "utils/profile_path.hpp"
#include <cassert>

namespace Module
{

const std::string ModuleRegistry::CONNECTIONS_FILE_PATH = utils::profile_path() + "/Connections.cfg";

// ---------------------------------------------------------------------------------------------------------------------

ModuleRegistry::ModuleRegistry()
	: pCmdRegistry_( NULL)
	, pMainWindow_( NULL)
	, pConnConfigFactory_( NULL)
	, pConnCfgWidgetFactory_( NULL)
	, pConnCfgCollection_( NULL)
{
}

// ---------------------------------------------------------------------------------------------------------------------

ModuleRegistry::~ModuleRegistry()
{
	ModuleMap::iterator iter = registeredModules_.begin(), endI = registeredModules_.end();
	while( iter != endI)
	{
		delete iter->second;
		++iter;
	}
}

// ---------------------------------------------------------------------------------------------------------------------

void ModuleRegistry::registerModule( AbstractModule* pModule )
{
	assert( registeredModules_.end() == registeredModules_.find( pModule->uid()));
	assert( NULL != pModule);

	pModule->initialize();

	registeredModules_.insert( std::make_pair( pModule->uid(), pModule));
}

// ---------------------------------------------------------------------------------------------------------------------

const AbstractModule& ModuleRegistry::module( const std::string& moduleID ) const
{
	assert( registeredModules_.end() != registeredModules_.find( moduleID));
	return *(registeredModules_.find( moduleID)->second);
}

// ---------------------------------------------------------------------------------------------------------------------

AbstractModule& ModuleRegistry::module( const std::string& moduleID )
{
	assert( registeredModules_.end() != registeredModules_.find( moduleID));
	return *(registeredModules_.find( moduleID)->second);
}

// ---------------------------------------------------------------------------------------------------------------------

bool ModuleRegistry::isModuleRegistered( const std::string& moduleID ) const
{
	return registeredModules_.end() != registeredModules_.find( moduleID);
}

// ---------------------------------------------------------------------------------------------------------------------

bool ModuleRegistry::isModuleRegistered( const AbstractModule& module ) const
{
	return this->isModuleRegistered( module.uid());
}

// ---------------------------------------------------------------------------------------------------------------------

void ModuleRegistry::configure( 
	AbsUI::MainWindow* pMainWindow, AbsUI::UICommandRegistry* pUICommandReg, AbsUI::ConnCfgWidgetFactory* pConnCfgWidgetFactory, 
	Storage::ConnectionConfigFactory* pConnCfgFactory, Storage::ConnectionConfigCollection* pConnCfgColl)
{
	assert( NULL == ModuleRegistry::instance().pMainWindow_);
	assert( NULL == ModuleRegistry::instance().pCmdRegistry_);
	assert( NULL == ModuleRegistry::instance().pConnConfigFactory_);
	assert( NULL == ModuleRegistry::instance().pConnCfgWidgetFactory_);
	assert( NULL == ModuleRegistry::instance().pConnCfgCollection_);
	assert( NULL != pMainWindow);
	assert( NULL != pUICommandReg);
	assert( NULL != pConnCfgFactory);
	assert( NULL != pConnCfgWidgetFactory);
	assert( NULL != pConnCfgColl);
	ModuleRegistry::instance().pMainWindow_ = pMainWindow;
	ModuleRegistry::instance().pCmdRegistry_ = pUICommandReg;
	ModuleRegistry::instance().pConnConfigFactory_ = pConnCfgFactory;
	ModuleRegistry::instance().pConnCfgWidgetFactory_ = pConnCfgWidgetFactory;
	ModuleRegistry::instance().pConnCfgCollection_ = pConnCfgColl;

	ModuleRegistry::instance().registerModule( new DefaultModule);
}

// ---------------------------------------------------------------------------------------------------------------------

ModuleRegistry& ModuleRegistry::instance()
{
	static ModuleRegistry INSTANCE;
	return INSTANCE; 
}

} // namespace Module
